package com.dysoft.flesh.gl;

import com.dysoft.flesh.RenderComponent;
import com.dysoft.flesh.RenderContext;
import com.sun.opengl.util.BufferUtil;

import javax.media.opengl.GL;
import javax.media.opengl.GLContext;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

/**
 * @author Sean Micklethwaite
 *         Aug 16, 2010 8:08:38 PM
 */
public class GLVertexBuffer extends GLObject implements RenderComponent {
	public static enum Type {
		VERTICES, NORMALS, COLORS, TEX_COORDS
	}

	final Type type;

	public GLVertexBuffer(FloatBuffer data, Type type) {
		super(genBuffer(GLContext.getCurrent().getGL()));
		GL gl = GLContext.getCurrent().getGL();
		gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, handle);
		gl.glBufferDataARB(GL.GL_ARRAY_BUFFER_ARB, data.remaining() * BufferUtil.SIZEOF_FLOAT,
				data, GL.GL_STATIC_DRAW_ARB);
		this.type = type;
	}

	public GLVertexBuffer(float [] data, Type type) {
		this(FloatBuffer.wrap(data), type);
	}

	public void activate(RenderContext ctx) {
		GL gl = ((GLRenderer.GLRenderContext)ctx).getGL();

		gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, handle);
		switch(type) {
			case VERTICES:
				gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
				gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
				break;
			case NORMALS:
				gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
				gl.glNormalPointer(GL.GL_FLOAT, 0, 0);
				break;
			case COLORS:
				gl.glEnableClientState(GL.GL_COLOR_ARRAY);
				gl.glColorPointer(4, GL.GL_FLOAT, 0, 0);
				break;
			case TEX_COORDS:
				gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
				gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0);
				break;
		}
	}

	public void deactivate(RenderContext ctx) {
		GL gl = GLContext.getCurrent().getGL();

		switch(type) {
			case VERTICES:
				gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
				break;
			case NORMALS:
				gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
				break;
			case COLORS:
				gl.glDisableClientState(GL.GL_COLOR_ARRAY);
				break;
			case TEX_COORDS:
				gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
				break;
		}
	}

	static int genBuffer(GL gl) {
		IntBuffer buf = IntBuffer.allocate(1);
		gl.glGenBuffersARB(1, buf);
		return buf.get(0);
	}
}
